
#include<iostream>
using namespace std;
#include<cstring>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<cassert>
#include<unordered_map>
#include<vector>

typedef void (*functor)();
vector<functor> functors;
unordered_map<uint32_t,string> info;
void f1()
{
  cout << "这是一个处理日志的任务, 执行的进程 ID [" << getpid() << "]"
         << "执行时间是[" << time(nullptr) << "]\n" << endl;
}
void f2()
{
    cout << "这是一个备份数据任务, 执行的进程 ID [" << getpid() << "]"
         << "执行时间是[" << time(nullptr) << "]\n" << endl;
}
void f3()
{
    cout << "这是一个处理网络连接的任务, 执行的进程 ID [" << getpid() << "]"
         << "执行时间是[" << time(nullptr) << "]\n" << endl;
}
void loadFunctor()
{
  info.insert({functors.size(),"处理日志的任务"});
  functors.push_back(f1);

  info.insert({functors.size(),"备份数据任务"});
  functors.push_back(f2);

  info.insert({functors.size(),"处理网络连接的任务"});
  functors.push_back(f3);

}
int main()
{
  loadFunctor();
  int pipefd[2];
  if(pipe(pipefd)!=0)
  {
    cerr<<"pipe error"<<endl;
    return 1;
  }
  pid_t id=fork();
  if(id<0)
  {
    cerr<<"fork error"<<endl;
  }
  else if(id==0)
  {
    close(pipefd[1]);
    while(true)
    {
      uint32_t operatorType=0;
      ssize_t s=read(pipefd[0],&operatorType,sizeof(uint32_t));
      if(s==0)
      {
        cout << "我要退出啦,我是给人打工的,老板都走了...." << endl;
        break;
      }
      assert(s==sizeof(uint32_t));
      (void)s;
      if(operatorType<functors.size())
      {
        functors[operatorType]();
        cout<<info[operatorType]<<" ================= "<<endl;
      }
      else
      {
        cerr<<"bug:operatorType = "<< operatorType <<endl;
      }
    }
    close(pipefd[0]);
    exit(0);
  }
  else
  {
    close(pipefd[0]);  
    srand((unsigned int)time(nullptr));
    int num=functors.size();
    int cnt=10;
    while(cnt--)
    {
      uint32_t commandCode=rand()%num;
      std::cout << "父进程指派任务完成，任务是: " 
          << info[commandCode] << " 任务的编号是: " << cnt << std::endl;
      write(pipefd[1],&commandCode,sizeof(uint32_t));
      sleep(1);
    }
    close(pipefd[1]);  
    pid_t res=waitpid(id,nullptr,0);
    if(res==0)
    {
      cout<<"wait success"<<endl;
    }
  }
  return 0;
}
